#include <cpu.hh>
#include <stdexcept>
#include <chrono>
#include <thread>

void cpu_load::init_cpu_usage()
{
    FILE *file = fopen(this->proc_file.c_str(),"r");
    auto retval = fscanf(file, "cpu %lu %lu %lu %lu", &lastTotalUser, &lastTotalUserLow,&lastTotalSys, &lastTotalIdle);
    if(retval < 0) {
        fclose(file);
        throw std::runtime_error("init cpu usage crash");
    }

    fclose(file);
}

double cpu_load::get_current_cpu_usage() {
    double percent;
    FILE *file;
    unsigned long long totalUser, totalUserLow, totalSys, totalIdle, total;

    file = fopen(this->proc_file.c_str(), "r");
    auto retval = fscanf(file, "cpu %llu %llu %llu %llu", &totalUser, &totalUserLow,
                         &totalSys, &totalIdle);
    fclose(file);
    if (retval < 0) {
        throw std::runtime_error("init cpu usage crash");
    }

    if (totalUser < lastTotalUser || totalUserLow < lastTotalUserLow ||
        totalSys < lastTotalSys || totalIdle < lastTotalIdle) {
        //Overflow detection. Just skip this value.
        percent = -1.0;
    } else {
        total = (totalUser - lastTotalUser) + (totalUserLow - lastTotalUserLow) +
                (totalSys - lastTotalSys);
        percent = total;
        total += (totalIdle - lastTotalIdle);
        percent /= total;
        percent *= 100;
    }

    lastTotalUser = totalUser;
    lastTotalUserLow = totalUserLow;
    lastTotalSys = totalSys;
    lastTotalIdle = totalIdle;

    return percent;
}
cJSON* cpu_load::to_json()
{
     cJSON* cjson_cpu = cJSON_CreateObject();

     init_cpu_usage();
     std::this_thread::sleep_for(std::chrono::seconds(1));
     double usage = get_current_cpu_usage();
     cJSON_AddNumberToObject(cjson_cpu, "usage_percent", usage);
     return cjson_cpu;

}
const char* cpu_load::get_name()
{
    return "cpu_load";
}
cpu_load::~cpu_load(){
    
}